package vpc.ext.vstack.util;

/**
 * The purpose of this class is to provide a set of conditional debugging tools, including
 * boolean flags (whether to print debugging information) and input/output sources.
 * @author Philip Russell
 *
 */

import java.io.InputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import java.io.PrintStream;

public class Debug {
	
	private static PrintStream out = System.out;
	private static final java.util.Properties props = new Properties();
	private static final String optionsString = "vdebug.properties";
	
	private static final String filePathNotFoundMessage = 
			"Lookup of property named '" + optionsString + "' failed.";
	
	public static final String seperator1 = "\n#######################################\n";

	public enum Flag {
		
		STAGE("STAGE", false),
		PRINTGRAPH("PRINTGRAPH", false),
		GRAPHVISITOR("GRAPHVISITOR", false),
		ALL("ALL", false),
		DATAHANDLER("TYPEHANDLER", false),
		GET_STACK_PUSH("GET_STACK_PUSH", false),
		INTR_MASK("INTR_MASK", false),
		VISIT_TIRCALL("VISIT_TIRCALL", false);
		
		protected final String name;
		protected boolean value;
		
		Flag(String name, boolean value) {
			this.name = name;
			this.value = value;
		}
		
		public boolean isSet() {
			return this.value;
		}
		
		public String toString() {
			return "(" + this.name + ", " + this.value + ")";
		}
	}
			
	public static void init() throws java.io.IOException {
//	static {
		String pathName = System.getProperty(optionsString);
		
		if (pathName == null) {
			throw new IOException(filePathNotFoundMessage);
		} 
		
		InputStream instream = new FileInputStream(pathName);
		props.load(instream);
		instream.close();
		instream = null;
		
		for (Flag flag : Debug.Flag.values()) {
			String value = props.getProperty(flag.name);
			if (value == null || value.equals("")) {
				continue;
			} else {
				flag.value = Boolean.parseBoolean(value);
			}
		}
//	}
		
		return;
	}
	
	public static void init(PrintStream ostream) throws IOException {
		Debug.out = ostream;
		Debug.init();
		return;
	}
	
	public static void print(Object o, Flag f) {
		if (f.isSet() || Debug.Flag.ALL.isSet()) {
			Debug.out.print(o);
		}
		return;
	}
	
	public static void println(Object o, Flag f) {
		if (f.isSet() || Debug.Flag.ALL.isSet()) {
			Debug.out.println(o);
		}
		return;
	}
}
